package com.gdit.zax.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.gdit.zax.entitys.VideoALL;

public class DBUtil {

	private static Connection conn;

	public static Connection getConnection() {
		try {
			if (!(conn == null || conn.isClosed())) {
				return conn;
			}

		LogUtil.print("正在连接数据库....");
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager
					.getConnection(
							"jdbc:mysql://zuiaixue.mysql.rds.aliyuncs.com:3306/zuiaixue?autoReconnect=true&useUnicode=true&characterEncoding=utf-8",
							"qq179157977", "ysproot");
//			conn = DriverManager
//			.getConnection(
//					"jdbc:mysql://10.0.16.16:4066/zuiaixue?useUnicode=true&characterEncoding=utf-8",
//					"M0JuyCWH", "vZpBJKlU2q36");
			
			
			LogUtil.print("连接数据库成功....");
		} catch (ClassNotFoundException e) {
			conn = null;
			LogUtil.print("连接数据库服务器错误");
			e.printStackTrace();
		} catch (SQLException e) {
			conn = null;
			LogUtil.print("SQL语法错误");
			e.printStackTrace();
		}
		return conn;
		
//		return null;
	}

	public static void closeAll(Connection conn, Statement stat, ResultSet rs) {
		LogUtil.print("正在关闭数据库连接....");
		
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		if (stat != null) {
			try {
				stat.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		LogUtil.print("关闭数据库连接完成....");
	}

	private static Map<Class,Map<Field, Method>> map_classFM;
	public static <T> T getobject(ResultSet rs, Class<T> cls) {
		//变量初始化
		if (map_classFM==null) {
			map_classFM = new HashMap<Class, Map<Field, Method>>();
		}
		Map<Field, Method> map = map_classFM.get(cls);
		if (map==null) {
			map = new HashMap<Field, Method>();
			
			for (Field fie : cls.getDeclaredFields()) {
				for (Method setmethod : cls.getMethods()) {
					if (setmethod.getName().equalsIgnoreCase("set" + fie.getName())) {
						map.put(fie, setmethod);
					}
				}
			}
			
			map_classFM.put(cls, map);
		}
		
		//建立object
		T newT = null ;
		try {
			newT = cls.newInstance();
			for (Field fie : map.keySet()) {
				Method setmethod = map.get(fie);
				try {
					Object newvar = null;
					
					//主要基本数据类型
					if (fie.getType().equals(int.class) || fie.getType().equals(Integer.class)) {//
						newvar = rs.getInt(fie.getName());//rs.get可以忽略大小写
					} else if (fie.getType().equals(float.class) || fie.getType().equals(Float.class)) {//
						newvar = rs.getFloat(fie.getName());
					} else if (fie.getType().equals(double.class) || fie.getType().equals(Double.class)) {//
						newvar = rs.getDouble(fie.getName());
					} else if (fie.getType().equals(boolean.class) || fie.getType().equals(Boolean.class)) {//
						newvar = rs.getBoolean(fie.getName());
					} else if (fie.getType().equals(char.class) || fie.getType().equals(Character.class)) {//
						newvar = rs.getCharacterStream(fie.getName()).read();
					} else if (fie.getType().equals(long.class) || fie.getType().equals(Long.class)) {//
						newvar = rs.getLong(fie.getName());
					} else if (fie.getType().equals(String.class)) {//String
						newvar = rs.getString(fie.getName());
						
					//其它次要类型
					} else if (fie.getType().equals(Date.class)) {//Date类型
						newvar = rs.getDate(fie.getName());
					} else if (fie.getType().equals(Timestamp.class)) {//自动生成的Timestamp类型
						newvar = rs.getTimestamp(fie.getName());
					} else {
						newvar = rs.getObject(fie.getName());			
					}
					
					
					//invoke进去
					if (newvar != null)
						setmethod.invoke(newT, newvar);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return newT;
	}
	
	
	public static boolean saveobject(Connection conn,String table,String where,Object obj) {
		if (conn==null) return false;
		
		try {
			StringBuffer sb = new StringBuffer("update " + table + " set ");
//			sql = "update t_user set Accesstoken=?,Device=?,LoginIP=? where Id=?";
			for (Field fie : obj.getClass().getDeclaredFields()) {
				try {
					fie.setAccessible(true);
					Object sobj = fie.get(obj);
					if (sobj!=null) {
						if (String.class.equals(sobj.getClass())) {
							if (sobj.toString()!=null) {
								sb.append(fie.getName() + "='" + sobj.toString() + "',");
							}
						} else if (int.class.equals(sobj.getClass()) || float.class.equals(sobj.getClass())){
							sb.append(fie.getName() + "=" + sobj.toString() + ",");
						} else {
							if (sobj.toString()!=null) {
								sb.append(fie.getName() + "='" + sobj.toString() + "',");
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			sb.deleteCharAt(sb.length()-1);//删除最后一个","号
			sb.append(" where " + where);
			String sql = sb.toString();
			LogUtil.print("updata sql : " + sql);
			int result = conn.prepareStatement(sql).executeUpdate();
			if (result!=0) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	//cls字段命名：1.普通字段：表面_字段名   2.统计字段count(t.id)变成_count_t_id (t是查询时as出来的) now()变成_now
	private static Map<Class,Map<String,Integer>> map_classjCM = new HashMap<Class, Map<String,Integer>>();//字段名统一到小写,结果集索引
	public static <T> T getJoinObject(ResultSet rs, Class<T> cls) {
		//变量初始化
		if (map_classFM==null) {
			map_classFM = new HashMap<Class, Map<Field, Method>>();
		}
		Map<Field, Method> map = map_classFM.get(cls);
		if (map==null) {
			map = new HashMap<Field, Method>();
			
			for (Field fie : cls.getDeclaredFields()) {
				for (Method setmethod : cls.getMethods()) {
					if (setmethod.getName().equalsIgnoreCase("set" + fie.getName())) {
						map.put(fie, setmethod);
					}
				}
			}
			
			map_classFM.put(cls, map);
		}
		
		if (map_classjCM==null) {
			map_classjCM = new HashMap<Class, Map<String,Integer>>();
		}
		Map<String,Integer> map2 = map_classjCM.get(cls);
		if (map2 == null) {
			map2 = new HashMap<String, Integer>();
			try {
				ResultSetMetaData rd = rs.getMetaData();
				for (int i = 1; i <= rd.getColumnCount(); i++) {
					String fieldname =  (rd.getTableName(i) + "_" + rd.getColumnName(i)).toLowerCase().replace("()", "").replace("(", "_").replace(")", "").replace(".", "_");
					map2.put(fieldname, i);
					LogUtil.print(fieldname + ">>" + i);
				}
				
				map_classjCM.put(cls, map2);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		//建立object
		T newT = null ;
		try {
			newT = cls.newInstance();
		for (Field fie : map.keySet()) {
			Integer column = map2.get(fie.getName().toLowerCase());
			if (column == null) {
				LogUtil.print("getisnull:" + fie.getName().toLowerCase());
			}
			Method setmethod = map.get(fie);
			try {
				Object newvar = null;
				
				//主要基本数据类型
				if (fie.getType().equals(int.class) || fie.getType().equals(Integer.class)) {//
					newvar = rs.getInt(column);
				} else if (fie.getType().equals(float.class) || fie.getType().equals(Float.class)) {//
					newvar = rs.getFloat(column);
				} else if (fie.getType().equals(double.class) || fie.getType().equals(Double.class)) {//
					newvar = rs.getDouble(column);
				} else if (fie.getType().equals(boolean.class) || fie.getType().equals(Boolean.class)) {//
					newvar = rs.getBoolean(column);
				} else if (fie.getType().equals(char.class) || fie.getType().equals(Character.class)) {//
					newvar = rs.getCharacterStream(column).read();
				} else if (fie.getType().equals(long.class) || fie.getType().equals(Long.class)) {//
					newvar = rs.getLong(column);
				} else if (fie.getType().equals(String.class)) {//String
					newvar = rs.getString(column);
					
				//其它次要类型
				} else if (fie.getType().equals(Date.class)) {//Date类型
					newvar = rs.getDate(column);
				} else if (fie.getType().equals(Timestamp.class)) {//自动生成的Timestamp类型
					newvar = rs.getTimestamp(column);
				} else {
					newvar = rs.getObject(column);			
				}
				
				
				//invoke进去
				if (newvar != null)
					setmethod.invoke(newT, newvar);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return newT;
	}
	
}
